package com.chenjl.trace.aspect;

import java.util.HashMap;
import java.util.Map;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.chenjl.trace.Tracer;
import com.chenjl.trace.enums.AnnotationEnum;
import com.chenjl.trace.enums.SpanTypeEnum;
import com.chenjl.trace.model.Endpoint;
import com.chenjl.trace.model.Span;
/**
 * 使用aspect对org.apache.httpcomponents httpclient4进行trace埋点
 * 2018-9-10 14:14:59
 * @author chenjinlong
 */
@Aspect
public class ApacheHttpClient4Aspect {
	private static final Logger log = LoggerFactory.getLogger(ApacheHttpClient4Aspect.class);
	
	@Pointcut("execution(public * org.apache.http.impl.client.CloseableHttpClient.execute(*))")
	public void getPointCut() {
		
	}
	
	@Around(value="getPointCut()")
	public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		Span rootSpan = Tracer.getRootSpan();
		if(rootSpan == null) {
			//无埋点的正常请求
			return proceedingJoinPoint.proceed();
		}
		
		CloseableHttpResponse closeableHttpResponse = null;
		int statusCode = 0;
		Throwable throwable = null;
		
		//GET or POST url
		HttpUriRequest httpUriRequest = (HttpUriRequest) proceedingJoinPoint.getArgs()[0];
		String url = httpUriRequest.getURI().toString();
		String methodName = httpUriRequest.getMethod();
		
		Endpoint endpoint = new Endpoint();
		endpoint.setServiceName("httpclient4 request");
		endpoint.setHost(url);
		String spanId = Tracer.begin(rootSpan.getTraceId(),rootSpan.getId(),url,endpoint,AnnotationEnum.CLIENT_SEND,SpanTypeEnum.APACHE_HTTPCLIENT4);
		
		boolean hasExceptionFlag = false;
		log.info(" -->--HttpClient4 invoke begin, url : {} ,methodName : {}",url,methodName);
		try {
			closeableHttpResponse = (CloseableHttpResponse) proceedingJoinPoint.proceed();
			statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
		}
		catch (Throwable e) {
			hasExceptionFlag = true;
			throwable = e;
		}
		
		Map<String,String> datas = new HashMap<String,String>(2);
		datas.put("hasException",String.valueOf(hasExceptionFlag));
		Tracer.end(spanId,endpoint,AnnotationEnum.CLIENT_RECEIVE,datas);
		log.info(" -->--HttpClient4 invoke begin, url : {} ,methodName : {}，error: {}, statusCode : {}",url,methodName,throwable!=null,statusCode);
		
		if(throwable != null) {
			throw throwable;
		}
		return closeableHttpResponse;
	}
}